/*
 * @lc app=leetcode.cn id=676 lang=golang
 *
 * [676] 实现一个魔法字典
 */
package Solutions

type searchTreeNode1 map[byte]searchTreeNode1

// @lc code=start
type MagicDictionary struct {
	prefixTreeMap map[int]searchTreeNode1
}

func Constructor() MagicDictionary {
	return MagicDictionary{}
}

func (this *MagicDictionary) BuildDict(dictionary []string) {
	// build prefix-search-tree
	this.prefixTreeMap = make(map[int]searchTreeNode1)
	for _, v := range dictionary {
		var node searchTreeNode1
		if n, ok := this.prefixTreeMap[len(v)]; ok {
			node = n
		} else {
			t := make(searchTreeNode1)
			this.prefixTreeMap[len(v)] = t
			node = t
		}
		for i := range v {
			if nextNode, ok := node[v[i]]; !ok {
				t := make(searchTreeNode1)
				node[v[i]] = t
				node = t

			} else {
				node = nextNode
			}

		}
	}

}

func sch(node searchTreeNode1, s string, index int, isModified bool) bool {
	if index >= len(s) {
		return isModified
	}
	if isModified {
		if nextNode, ok := node[s[index]]; ok {
			return sch(nextNode, s, index+1, isModified)
		} else {
			return false
		}
	} else {
		for key, childNode := range node {
			var falg = true

			if key == s[index] {
				falg = false
			}
			if sch(childNode, s, index+1, falg) {
				return true
			}

		}
	}
	return false

}

func (this *MagicDictionary) Search(searchWord string) bool {
	// search prefix
	node, ok := this.prefixTreeMap[len(searchWord)]
	if !ok {
		return false
	}
	return sch(node, searchWord, 0, false)

}

/**
 * Your MagicDictionary object will be instantiated and called as such:
 * obj := Constructor();
 * obj.BuildDict(dictionary);
 * param_2 := obj.Search(searchWord);
 */
// @lc code=end
